﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DomainDriver.DomainModeling.DomainObjects;
using DomainDriver.DomainModeling.Events;
using DomainDriver.DomainModeling.Queries;

namespace DomainDriver.DomainModeling.Repositories
{
    public interface IRepository<KEY, KEYED_DOMAIN_OBJECT> : IReadOnlyRepository<KEY, KEYED_DOMAIN_OBJECT>
        where KEYED_DOMAIN_OBJECT : IKeyedDomainObject<KEY, KEYED_DOMAIN_OBJECT>
    {
        event AddingDomainObjectDelegate<KEY, KEYED_DOMAIN_OBJECT> AddingDomainObject;
        event AddedDomainObjectDelegate<KEY, KEYED_DOMAIN_OBJECT> AddedDomainObject;
        event RemovingDomainObjectDelegate<KEY, KEYED_DOMAIN_OBJECT> RemovingDomainObject;
        event RemovedDomainObjectDelegate<KEY, KEYED_DOMAIN_OBJECT> RemovedDomainObject;
        event UpdatingDomainObjectDelegate<KEY, KEYED_DOMAIN_OBJECT> UpdatingDomainObject;
        event UpdatedDomainObjectDelegate<KEY, KEYED_DOMAIN_OBJECT> UpdatedDomainObject;

        void Add(KEYED_DOMAIN_OBJECT domainObject);
        void Remove(KEY domainObjectKey);
        void Update(KEYED_DOMAIN_OBJECT domainObject);
    }

    public interface IReadOnlyRepository<KEY, KEYED_DOMAIN_OBJECT>
        where KEYED_DOMAIN_OBJECT : IKeyedDomainObject<KEY, KEYED_DOMAIN_OBJECT>
    {
        IRepositoryInfoProvider InfoProvider { get; }
        IDictionary<KEY, KEYED_DOMAIN_OBJECT> ConvertToDictionary(ICollection<KEYED_DOMAIN_OBJECT> domainObjects);
        int Count();
        bool Exists(KEY key);
        bool Exists(ICollection<KEY> keys);
        ICollection<KEY> FindKeys();
        ICollection<KEY> FindKeys(IQuery<KEYED_DOMAIN_OBJECT> query);
        ICollection<KEYED_DOMAIN_OBJECT> Read();
        ICollection<KEYED_DOMAIN_OBJECT> Read(IQuery<KEYED_DOMAIN_OBJECT> query);
        ICollection<KEYED_DOMAIN_OBJECT> Read(ICollection<KEY> keys);
        KEYED_DOMAIN_OBJECT Read(KEY key);
    }
}